// 两种 js 中的函数

// // 命名函数
// function add(x, y) {
//   return x + y
// }

// // 匿名函数
// let myAdd = function(x, y) {
//   return x + y
// }

// 为函数定义类型
// function add(x: number, y: number): number {
//   return x + y
// }

// let myAdd = function(x: number, y: number): number {
//   return x + y
// }

// 完整函数类型
// let myAdd: (x: number, y: number) => number = function(x: number, y: number): number {
//   return x + y
// }

// 或者增加可读性
// let myAdd: (baseValue: number, increment: number) => number = function(x: number, y: number): number {
//   return x + y
// }

// 推断类型
// let myAdd: (baseValue: number, increment: number) => number = function(x, y) {
//   return x + y
// }

// 可选参数和默认参数
// function buildName (firstName: string, lastName: string) {
//   return firstName + ' ' + lastName
// }

// let result1 = buildName('Bob') // 报错，应有 2 个参数，但获得 1 个。
// let result2 = buildName('Bob', 'Smith', 'Adams') // 报错，应有 2 个参数，但获得 3 个。
// let result3 = buildName('Bob', 'Adams')

// 可选参数
// function buildName (firstName: string, lastName?: string) {
//   if (lastName) 
//     return firstName + ' ' + lastName
//   else
//   return firstName
// }

// let result1 = buildName('Bob')
// let result2 = buildName('Bob', 'Smith', 'Adams') // 报错，应有 1-2 个参数，但获得 3 个。
// let result3 = buildName('Bob', 'Adams')

// 默认初始化值
// function buildName (firstName: string, lastName = 'Smith') {
//   if (lastName) 
//     return firstName + ' ' + lastName
//   else
//   return firstName
// }

// let result1 = buildName('Bob')
// let result2 = buildName('Bob', 'Smith', 'Adams') // 报错，应有 1-2 个参数，但获得 3 个。
// let result3 = buildName('Bob', 'Adams')
// let result4 = buildName('Bob', undefined)


// function buildName (firstName = 'Will', lastName: string) {
//   if (lastName) 
//     return firstName + ' ' + lastName
//   else
//   return firstName
// }

// let result1 = buildName('Bob') // 报错，应有 2 个参数，但获得 1 个。
// let result2 = buildName('Bob', 'Smith', 'Adams') // 报错，应有 2 个参数，但获得 3 个。
// let result3 = buildName('Bob', 'Adams')
// let result4 = buildName(undefined, 'Bob')


// 剩余参数
// function buildName(firstName: string, ...restOfName: string[]) {
//   return firstName + ' ' + restOfName.join(' ')
// }

// let employeeName = buildName('Joseph', 'Samuel', 'Lucas', 'Mack')
// console.log(employeeName)

// let buildNameFun: (fname: string, ...rest: string[]) => string = buildName

// this 和 箭头函数
// let deck = {
//   suits: ['hearts', 'spades', 'clubs', 'diamonds'],
//   cards: Array(52),
//   createCardPicker: function() {
//     return function() {
//       let pickedCard = Math.floor(Math.random() * 52)
//       let pickedSuit = Math.floor(pickedCard / 13)
//       return { suit: this.suits[pickedSuit], card: pickedCard % 13 } // 报错，this 为 window 
//     }
//   }
// }

// let cardPicker = deck.createCardPicker()
// let pickedCard = cardPicker()

// alert('card:' + pickedCard.card + 'of' + pickedCard.suit)

interface Card {
  suit: string
  card: number
}

interface Deck {
  suits: string[]
  cards: number[]
  createCardPicker(this: Deck): () => Card
}

let deck: Deck = {
  suits: ['hearts', 'spades', 'clubs', 'diamonds'],
  cards: Array(52),
  createCardPicker: function(this: Deck) {
    return () => {
      let pickedCard = Math.floor(Math.random() * 52)
      let pickedSuit = Math.floor(pickedCard / 13)
      return { suit: this.suits[pickedSuit], card: pickedCard % 13 }
    }
  }
}

let cardPicker = deck.createCardPicker()
let pickedCard = cardPicker()

console.log('card:' + pickedCard.card + ' of ' + pickedCard.suit)


